
//--Yangxin--
`timescale 1ns / 1ps

module Imm_Extractor(
	input wire  [31:0] instruction  ,
	input wire  [ 5:0] inst_imm_type_sel,
	output reg [63:0] value
);

	wire [11:0] Imm_11_0   = instruction[31:20];
	wire [19:0] Imm_31_12  = instruction[31:12];
	wire [ 4:0] Imm_4_0    = instruction[ 11:7];
	wire [ 6:0] Imm_11_5   = instruction[31:25];
	wire        Imm_11_B   = instruction[7];
	wire [ 3:0] Imm_4_1    = instruction[11:8];
	wire [ 5:0] Imm_10_5   = instruction[30:25];
	wire 		Imm_12     = instruction[31];
	wire [ 7:0] Imm_19_12  = instruction[19:12];
	wire 		Imm_11_J   = instruction[20];
	wire [ 9:0] Imm_10_1   = instruction[30:21];
	wire 		Imm_20	   = instruction[31];

	//Extend bits and get immediate values of types
	wire signed [63:0] Imm_I  = {{52{Imm_11_0[11]}},Imm_11_0};
	wire signed [63:0] Imm_U  = {{32{Imm_31_12[19]}}, Imm_31_12,12'h0};
	wire signed [63:0] Imm_B  = {{52{Imm_12}}, Imm_11_B, Imm_10_5, Imm_4_1, 1'b0};
	wire signed [63:0] Imm_S  = {{52{Imm_11_5[6]}}, Imm_11_5, Imm_4_0};
	wire signed [63:0] Imm_UJ = {{44{Imm_20}}, Imm_19_12, Imm_11_J, Imm_10_1, 1'b0};

	always @(*) begin
		case(inst_imm_type_sel)
			6'b000001: value = Imm_I;
			6'b000010: value = Imm_U;
			6'b000100: value = Imm_B;
			6'b001000: value = Imm_S;
			6'b010000: value = Imm_UJ;
			default: begin
				value = 0;
			end
		endcase
	end
endmodule
